16.3. 条件和循环

表 1 显示,C 和 Java 中 if - else 语句的语法和语义相同。

表 1. Java 和 C 中 if-else 语句的语法比较

Java versionC version
/* Java if-else example */

import java.util.Scanner;

class IfExample {

public static void main(String[] args) {

int n1, n2;
Scanner in = new Scanner(System.in);

System.out.print("Enter 1st num: ");
n1 = in.nextInt();
System.out.print("Enter 2nd num: ");
n2 = in.nextInt();

if (n1 > n2) {
System.out.printf("%d is biggest\n",n1);
n2 = n1;
} else {
System.out.printf("%d is biggest\n",n2);
n1 = n2;
}
}

}
/* C if-else example */

#include <stdio.h>



int main(void) {

int n1, n2;


printf("Enter 1st num: ");
scanf("%d", &n1);
printf("Enter 2nd num: ");
scanf("%d", &n2);

if (n1 > n2) {
printf("%d is biggest\n",n1);
n2 = n1;
} else {
printf("%d is biggest\n",n2);
n1 = n2;
}

return 0;
}

Java 和 C 中 if-else 语句的语法相同。在两者中,else 部分都是可选的。Java 和 C 还通过链接 ifelse if 语句支持多路分支。以下描述了完整的 if-else C 语法:

    // a one-way branch:
    if ( <boolean expression> ) {
        <true body>
    }

    // a two-way branch:
    if ( <boolean expression> ) {
        <true body>
    }
    else {
        <false body>
    }

    // a multibranch (chaining if-else if-...-else)
    // (has one or more 'else if' following the first if):
    if ( <boolean expression 1> ) {
        <true body>
    }
    else if ( <boolean expression  2> ) {
        // first expression is false, second is true
        <true 2 body>
    }
    else if ( <boolean expression  3> ) {
        // first and second expressions are false, third is true
        <true 3 body>
    }
    // ... more else if's ...
    else if ( <boolean expression  N> ) {
        // first N-1 expressions are false, Nth is true
        <true N body>
    }
    else { // the final else part is optional
        // if all previous expressions are false
        <false body>
    }

16.3.1. C 语言中的布尔值

C 不提供具有真或假值的布尔类型。相反,整数值在条件语句中使用时计算结果为 truefalse。在条件表达式中使用时,任何整数表达式:

  • 零 (0) 计算结果为 false
  • 非零(任何正值或负值) 计算结果为

C 有一组用于布尔表达式的关系运算符和逻辑运算符,与 Java 的关系运算符和逻辑运算符相同。

关系运算符 采用相同类型的操作数,并计算结果为零(假)或非零(真)。关系运算符集包括:

  • 相等(==)和不等(不等,!=
  • 比较运算符:小于(<)、小于或等于(<=)、大于(>)和大于或等于(>=

以下是一些显示关系运算符示例的 C 代码片段:

// assume x and y are ints, and have been assigned
// values before this point in the code

if (y < 0) {
    printf("y is negative\n");
} else if (y != 0) {
    printf("y is positive\n");
} else {
    printf("y is zero\n");
}

// set x and y to the larger of the two values
if (x >= y) {
    y = x;
} else {
    x = y;
}

C 的 逻辑运算符 采用整数“布尔”操作数,其计算结果为零(假)或非零(真)。逻辑运算符集包括:

  • 逻辑否定(!)
  • 逻辑与(&&):在第一个错误表达式处停止评估(短路)
  • 逻辑或(||):在第一个真表达式处停止评估(短路)

C 的 短路 逻辑运算符求值在知道结果后立即停止求值逻辑表达式。例如,如果逻辑与(&&)表达式的第一个操作数求值为假,则 && 表达式的结果必定为假。因此,第二个操作数的值不需要求值,也不会被求值。

以下是 C 语言中使用逻辑运算符的条件语句的示例(最好在复杂的布尔表达式周围使用括号以使其更易于阅读):

if ( (x > 10) && (y >= x) ) {
    printf("y and x are both larger than 10\n");
    x = 13;
} else if ( ((-x) == 10) || (y > x) ) {
    printf("y might be bigger than x\n");
    x = y * x;
} else {
    printf("I have no idea what the relationship between x and y is\n");
}

16.3.2. C 中的循环

Java 和 C 都具有对重复代码序列的语言级别支持。与 Java 一样,C 也支持 forwhiledo-while 循环。这两种语言的语法和语义相同。Java 还支持对集合进行迭代,而 C 则不支持。

while循环

C 和 Java 中的 while 循环语法相同,行为也相同。表 2 显示了带有 while 循环的示例 C 程序。

表 2. C 语言中的 while 循环语法

C while loop example
/* C while loop example */

#include <stdio.h>

int main(void) {

int num, val;

printf("Enter a value: ");
scanf("%d", &num);
// make sure num is not negative
if (num < 0) {
num = -num;
}
val = 1;
while (val < num) {
printf("%d\n", val);
val = val * 2;
}

return 0;
}

C 中的 while 循环语法与 Java 中的相同,并且都以相同的方式进行评估:

while ( <boolean expression> ) {
    <true body>
}

while 循环首先检查布尔表达式,如果为真则执行循环体。在上面的示例程序中,val 变量的值将在 while 循环中重复打印,直到其值大于 num 变量的值。如果用户输入 10,C 和 Java 程序将打印:

1
2
4
8

Java 和 C 也有一个 do-while 循环,它与 while 循环类似,但它首先执行循环体,然后检查条件,只要条件为真,就重复执行循环体。也就是说,do-while 循环总是会执行循环体至少一次:

do {
    <body>
} while ( <boolean expression> );

要获取更多 while 循环示例,请尝试以下两个程序:

for循环

C 中的 for 循环与 Java 中的 for 循环相同,并且它们的评估方式相同。C(和 Java)for 循环语法为:

for ( <initialization>; <boolean expression>; <step> ) {
    <body>
}

for 循环评估规则是:

  1. 第一次进入循环时,评估一次 initialization
  2. 计算布尔表达式的值。如果为 0(假),则退出 for 循环(即程序已完成重复循环体语句)。
  3. 评估循环主体内(body)的语句。
  4. 评估 step 表达式。
  5. 从步骤(2)开始重复。

这是一个简单的示例 for 循环,用于打印值 0、1 和 2:

int i;

for (i = 0; i < 3; i++) {
    printf("%d\n", i);
}

在前面的循环中执行 for 循环评估规则会产生以下操作序列:

(1) eval init: i is set to 0  (i=0)
(2) eval bool expr: i < 3 is true
(3) execute loop body: print the value of i (0)
(4) eval step: i is set to 1  (i++)
(2) eval bool expr: i < 3 is true
(3) execute loop body: print the value of i (1)
(4) eval step: i is set to 2  (i++)
(2) eval bool expr: i < 3 is true
(3) execute loop body: print the value of i (2)
(4) eval step: i is set to 3  (i++)
(2) eval bool expr: i < 3 is false, drop out of the for loop

以下程序展示了一个更为复杂的 for 循环示例(也可以下载)。请注意,仅仅因为 C 支持 for 循环,并且其 初始化单步步骤 部分都有一串语句,所以最好保持简单(此示例说明了一个更为复杂的 for 循环语法,但如果通过将 j += 10 步骤语句移到循环体末尾并只包含一个步骤语句 i += 1 来简化 for 循环,它将更易于阅读和理解)。

/* An example of a more complex for loop which uses multiple variables.
 * (it is unusual to have for loops with multiple statements in the
 * init and step parts, but C supports it and there are times when it
 * is useful...don't go nuts with this just because you can)
 */
#include <stdio.h>

int main(void) {
    int i, j;

    for (i=0, j=0; i < 10; i+=1, j+=10) {
        printf("i+j = %d\n", i+j);
    }

    return 0;
}

// the rules for evaluating a for loop are the same no matter how
// simple or complex each part is:
// (1) evaluate the initialization statements once on the first
//     evaluation of the for loop:  i=0 and j=0
// (2) evaluate the boolean condition: i < 10
//     if false (when i is 10), drop out of the for loop
// (3) execute the statements inside the for loop body: printf
// (4) evaluate the step statements:  i += 1, j += 10
// (5) repeat, starting at step (2)

与 Java 一样,C 中的 for 循环和 while 循环的功能是等效的,这意味着任何 while 循环都可以表示为 for 循环,反之亦然。

考虑 C 语言中的以下 while 循环:

int guess = 0;

while (guess != num) {
    printf("%d is not the right number\n", guess);
    printf("Enter another guess: ");
    scanf("%d", &guess);
}

这个循环可以转换为 C 语言中等效的for循环:

int guess;

for (guess = 0; guess != num; ) {
    printf("%d is not the right number\n", guess);
    printf("Enter another guess: ");
    scanf("%d", &guess);
}

由于 forwhile 循环在 C 语言中表达能力相同,因此该语言只需要一个循环结构。但是,for 循环对于确定性循环(如迭代一系列值)来说是一种更自然的语言结构,而 while 循环对于不确定循环(如重复直到用户输入偶数)来说是一种更自然的语言结构。因此,C(和 Java)为程序员提供了这两种语言结构。